package com.smasher.update.component.update

import android.net.Uri
import android.util.Log
import com.smasher.update.component.check.CheckDelegate
import com.smasher.update.component.check.OnCheckListener
import com.smasher.update.component.download.DownloadDelegate
import com.smasher.update.component.download.DownloadFinishListener
import com.smasher.update.component.parse.OnParseListener
import com.smasher.update.component.parse.ParseDelegate
import org.json.JSONObject

/**
 * 版本检测
 * 检查执行器
 */
class UpdateExecutor(

    private val versionCheckImpl: CheckDelegate,//版本检查工具
    private val parseDelegate: ParseDelegate,//数据解析工具
    private val downloadDelegate: DownloadDelegate,//下载工具

    private var onParseListener: OnParseListener?,//解析监听器
    private var listener: DownloadFinishListener?//下载监听器

) {

    private val finishListener = object : DownloadFinishListener {
        override fun onDownload(id: Long) {
            listener?.onDownload(id)
        }
    }


    init {
        downloadDelegate.addDownloadFinishListener(finishListener)
    }

    //=================================================================

    fun checkVersion(
        ruleId: String,
        code: Long,
        silent: Boolean = false
    ) {
        versionCheckImpl.checkVersion(ruleId, code, silent, object : OnCheckListener {
            override fun onCheck(json: JSONObject) {
                parseActual(json) {
                    Log.d(TAG, "onCheck: $it")
                }
            }
        })
    }


    fun checkVersionOnly(
        ruleId: String,
        code: Long,
        silent: Boolean = false,
        callback: (Long) -> Unit
    ) {
        versionCheckImpl.checkVersion(ruleId, code, silent, object : OnCheckListener {
            override fun onCheck(json: JSONObject) {
                parseActual(json = json, only = true, callback = callback)
            }
        })
    }


    private fun parseActual(json: JSONObject, only: Boolean = false, callback: (Long) -> Unit) {
        Log.d(TAG, "onCheck: $json")
        parseDelegate.parse(json)

        val title = parseDelegate.getUpdateTitle()
        val content = parseDelegate.getUpdateContent()
        val versionCode = parseDelegate.getVersionCode()
        val type = parseDelegate.getType()
        val downloadUrl = parseDelegate.getDownLoadUrl()
        val updateTime = parseDelegate.getUpdateTime()

        if (!only) {
            Log.d(TAG, "parseActual: only check")

            onParseListener?.onParse(
                title,
                content,
                versionCode,
                type,
                downloadUrl,
                updateTime
            )
        }

        callback.invoke(versionCode)
    }


    fun downloadByUrl(): Long? {
        return downloadDelegate.startDownload(parseDelegate)
    }

    fun getDownloadUriById(id: Long): Uri? {
        return downloadDelegate.getDownloadUriById(id)
    }

    fun queryFinishedById(id: Long): Boolean? {
        return downloadDelegate.queryFinishedById(id)
    }

    fun release() {
        versionCheckImpl.release()
        downloadDelegate.release()
    }

    companion object {
        const val TAG = "CheckVer"
    }
}